/**
 * Parseur du site leboncoin.fr
 */
function LeBonCoin()
{
	var _name = "Le boncoin";
	var _codeName = "leboncoin.fr";
	var _ressourcesToLoad = ["icon.png"];
	var _labelColumns = [""]
	var _baseUrl = "http://www.leboncoin.fr/annonces/offres/"
	var _list_month = ["jan", "fév", "mars", "avril", "mai", "juin", "juillet", "août", "sept", "oct", "nov", "déc"]
    
	var _domexp_list = {
		container: "#ContainerMain .listing_thumbs",
		elements: "tbody tr",
		pages: "#result_left span",
		lastpage: "#result_right a",
		element: {
			name: "td[2] a",
			time: "td",
			image: "td[1] a img",
			price: "td[2]"
		}
	};
	
	var _domexp_byid = {
		name: ".lbc_links h1",
		time: ".lbcContainer",
		image: "#display_image img",
		all_images: ".lbcImages .thumb_images div",
		price: ".lbcParams .ad_details strong",
		description: ".AdviewContent .lbc_text"
	};

    // Le nom pour la prochaine page
	var _label_next_page = "Page suivante »"
	var _this = this;

    /**
     * Obtient le nom du site
     */
	this.getName = function(args) { return _name; }
    /**
     * Obtient le nom de code du site
     */
	this.getCodeName = function(args) { return _codeName; }
    /**
     * Obtient les ressources à charger
     */
	this.getRessourcesToLoad = function() { return _ressourcesToLoad; }

    /**
     * Obtient la première page de recherche
     *
     * Paramètre obligatoire:
     * search: la recherche
     *
     * Paramètres falcutatif:
     * type: le numéro de la rubrique
     *
     * @param {Object} args les paramètres de recherche
     */
	this.getFirstPageUrl = function(args) {
		
		var params = {};

        // Le type pour la recherche
		if (isset(args.type))
			params.f = args.type;
		
		params.q = args.search;
		
		return new URL(_baseUrl,params,URL.GET);
	}

    /**
     * Obtient l'URL pour un ID précis
     *
     * @param {String} id l'id voulu (obtenu via getId())
     */
	this.getPageUrlForId = function(id)
	{
		return URL.parse(id);
	};

    /**
     * Décodage de la page d'ID
     */
	var idPage = {};

    /**
     * Décode le prix selon l'élément HTML en question
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le prix
     */
	idPage.decodePrice = function(element) { return element.innerText.trim(); }
    /**
     * Décode le nom selon l'élément HTML en question
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le nom
     */
	idPage.decodeName = function(element) { return element.innerText.trim(); }

    /**
     * Décode l'image selon l'élément HTML en question
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le lien de l'image
     */
	idPage.decodeImage = function(element) {
		if (element)
			return element.getAttribute("_src");
		else
			return "";
	};

    /**
     * Décode la description selon l'élément HTML en question
     *
     * @return {String} la description
     */
	idPage.decodeDescription = function(element) {
		return element.innerHTML.replace(/<br>/gi,"\n");
	};

    /**
     * Décode la date de l'annonce selon l'élément HTML en question
     * Exemple de format: le 10 décembre à 10h11
     *
     * @param {Object} element l'élément correspondant
     * @return {Date} la date
     */
	idPage.decodeTime = function(element) {
		
		var textTime = element.childNodes[6].nodeValue.trim();
		var aTime = textTime.split(" ");

        // Le jour est après le 2ème espace (après 'le')
		var day = parseInt(aTime[1]);
        // Le mois se situe juste après le jour
		var smonth = aTime[2];

        // L'heure de l'annonce après le "à"
		aTime = aTime[4].split(":");

        // les heures en premier, au lieu des minutes
		var hours = parseInt(aTime[0]);
		var minutes = parseInt(aTime[1]);

        // La liste des mois
		var listmonths = _list_month;
		var month = -1;

        // On essaye de trouver le mois
		for (var i = 0; i < listmonths.length; i++)
		{
			if (smonth.beginsWith(listmonths[i]))
			{
				month = i;
				break;
			}
		}

        // Si on ne le trouve pas, erreur
        // TODO: enregistrer l'erreur dans un rapport
		if (month == "-1")
			console.log("Impossible de décoder le mois "+smonth);

        // Création de l'objet date correspondant
		var d = new Date();
        // Le jour demandé commence par 0 pour l'objet Date
		d.setDate(day-1);
		d.setMonth(month);
		d.setHours(hours);
		d.setMinutes(minutes);
		d.setSeconds(0);
		d.setMilliseconds(0);
		
		return d;
	}

    /**
     * Décodage de la liste renvoyé par une recherche
     */
	var listPage = {};

    /**
     * Décodage du prix: 4ème élément
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le prix
     */
	listPage.decodePrice = function(element) { return element.childNodes[4].nodeValue.trim(); }
    /**
     * Décodage du nom: tout le contenu
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le nom de l'objet
     */
	listPage.decodeName = function(element) { return element.innerHTML.trim(); }
    /**
     * Décodage du lien: l'attribut href
     *
     * @param {Object} element l'élément correspondant
     * @return {String} le lien
     */
	listPage.decodeLink = function(element) { return element.getAttribute("href"); }
    /**
     * Décodage de l'image
     * 
     * @param {Object} element l'élément correspondant
     * @return {String} le lien de l'image
     */
	listPage.decodeImage = function(element) { 
		if (element) 
			return element.getAttribute("_src") 
		else return ""; 
	}

    /**
     * Décodage de la date de publication
     * Exemple de format: 14 déc<br>10h11
     *
     * Attention: Pour la date actuelle: Aujourd'hui, et la date de jour précédent: Hier
     *
     * @param {Object} element l'élément correspondant
     * @return {Date} la date
     */
	listPage.decodeTime = function(element) { 
		
		var strtime = element.innerHTML.trim().split("<br>");
		
		var date = new Date();
		var hour = strtime[1].split(":");

        // Si c'est Hier, date -1
		if (strtime[0] == "Hier")
			date.setDate(date.getDate()-1);
        // Parsage de la date si ce n'est pas aujourd'hui
		else if (strtime[0] != "Aujourd'hui")
		{
			var strdate = strtime[0].split(" ");
            // Le jour, 1er élément
			var day = parseInt(strdate[0])

            // Liste des mois
			var listmonths = _list_month;
			var month = -1;

            // Le mois, deuxième élément
			for (var i = 0; i < listmonths.length; i++)
			{
				if (strdate[1].beginsWith(listmonths[i]))
				{
					month = i;
					break;
				}
			}

            // Si on ne le trouve pas, erreur
            // TODO: Ajoutez cela dans le rapport d'erreur
			if (month == "-1")
				console.log("Impossible de décoder le mois "+strdate[1]);
			
			date.setMonth(i);
			date.setDate(day);
		}
		date.setHours(parseInt(hour[0]))
		date.setMinutes(parseInt(hour[1]));
		date.setSeconds(0);
		
		// console.log(date.toDateString()+" - "+date.toTimeString())
		return date;
	}

    /**
     * Décode un objet précis et renvoie un ItemWebsite
     *
     * @param {Object} element l'élément correspondant
     * @return {ItemWebsite} l'objet correspondant
     */

	listPage.decodeItem = function(element) {
		
        // On récupère la liste des éléments par groupe
		var results = _this.parseWithArrayOfDOMExp(element, _domexp_list.element);

        // Erreur si on ne trouve pas le nom
        // TODO: Rapport d'erreur
		if (!results.name)
		{
			console.log("Impossible d'avoir l'objet")
			return null;
		}

        // Parsage des différents éléments
		var params = {};
		params.price = listPage.decodePrice(results.price);
		params.name = listPage.decodeName(results.name);
		params.link = params.id = listPage.decodeLink(results.name);
		params.image = listPage.decodeImage(results.image);
		params.date = listPage.decodeTime(results.time);

        // Création de l'objet
		var item = new ItemWebsite(params);
		//console.log(item);
		
		return item;
	}

    /**
     * Décode la liste des pages disponibles
     *
     * @param {Object} elements les éléments nécessaires correspondantes aux pages
     *
     * @return {Object} liste des pages URL correspondantes, avec en plus la prochaine page
     */
	listPage.decodePages = function(elements)
	{
		var obj = {}
		
		var pages = [];
		for (var i = 0; i < elements.length; i++)
		{
            // On prend le <a> disponible
			var link = elements[i].getElementsByTagName("a")[0];
			var url = URL.parse(link.href);

			var p = getPageFromURL(url);

			pages.push(p);

            // Si on trouve "Page suivante", on y indique la prochaine page
			if (link.innerHTML.trim() == _label_next_page)
				obj.next = p;
		}
		obj.pages = pages;
		return obj;
	}

    /**
     * Décode la dernière page disponible
     *
     * @param {Object} element l'élément nécessaire
     *
     * @return {PageURL} la PageURL correspondant
     */
	listPage.decodeLastPage = function(element) {
		var url = URL.parse(element.href)
		return getPageFromURL(url);
	}
	
	/**
     * Obtient un objet PageURL selon l'URL
     *
     * @param {URL} url l'URL demandé
     * @return {PageURL} l'objet PageURL correspondant
     */
	function getPageFromURL(url)
	{
		return new PageURL(url, parseInt(url.params.o))
	}

    /**
     * Parse le DOM reçu via AJAX correspondant à une page de description d'un id
     *
     * @param {String} id l'id demandé
     * @param {Object} element l'élément du DOM correspondant
     *
     * @return {ItemWebsite} l'item correspondant
     */
	this.parseDomAndGetPageById = function(id, element)
	{
		var results = _this.parseWithArrayOfDOMExp(element, _domexp_byid);
		
		var obj = {};

        // Parsage des différents attributs
		obj.description = idPage.decodeDescription(results.description);
		obj.name = idPage.decodeName(results.name);
		obj.price = idPage.decodePrice(results.price);
		obj.image = idPage.decodeImage(results.image);
		obj.time = idPage.decodeTime(results.time);
		obj.id = obj.link = id;
		
		var item = new ItemWebsite(obj);
		return item;
	};

    /**
     * Parse le DOM reçu via AJAX correspondant à une page de recherche
     *
     * @param {Object} domdoc l'élément du DOM correspondant
     *
     * @return {WebsitePage} l'item correspondant
     */
	this.parseDomAndGetPage = function(domdoc) {

        // Le conteneur
      	var container = this.parseWithDOMExp(domdoc, _domexp_list.container, true);

        // Les objets trouvé par la recherche
		var elements = this.parseWithDOMExp(container, _domexp_list.elements)
		
		var items = [];

        // décodage de chaque objet
		for (var i = 0; i < elements.length; i++)
		{
			var item = listPage.decodeItem(elements[i]);
			if (item)
				items.push(item);
		}

        // la liste des pages et la dernière page
		var dompages = this.parseWithDOMExp(domdoc, _domexp_list.pages);
		var domlastpage = this.parseWithDOMExp(domdoc, _domexp_list.lastpage, true);
		
		var lastpage = null;
		var pages = [];
		var nextpage = null;
		var num_page = 1;

        // Récupération du total de pages
		if (domlastpage)
		{
			lastpage = listPage.decodeLastPage(domlastpage);
			num_page = lastpage.page_index;
		}

        // Récupération des pages
		if (dompages.length > 0)
		{
			var opages = listPage.decodePages(dompages);
			pages = opages.pages;
			nextpage = opages.next;
		}

        // Création de la WebsitePage
		var pageweb = new WebsitePage(items, pages, nextpage, num_page)
		return pageweb;
	}
	
	
	this.renderItem = function(item) { }
	this.getLabelColumns = function(columns) { }
}

// On fait un extends
LeBonCoin.$extends(Website);

